#ifndef __ALGO_NUM_H__
#define __ALGO_NUM_H__

#include "ct_type.h"

// calc square
int32_t square(int16_t x);

/***************************************
 * Array Statistics Functions
 ***************************************/
/**
 * @brief Set all elements in an array to a specified value
 * @param p Pointer to the array
 * @param value The value to set all elements in the array to (must be the same type as the array)
 * @param arr_size arr_size of the array
 */
void ArraySet(int16_t *p, int16_t value, uint16_t arr_size);

/**
 * @brief Calculate the average of all elements in an array
 * @param p Pointer to the array
 * @param arr_size arr_size of the array
 * @return The average of all elements in the array
 */
int32_t average(int16_t *p, uint16_t arr_size);

/**
 * @brief Calculate the median of an array
 * @param p Pointer to the array
 * @param arr_size arr_size of the array
 * @return The median of the array
 */
int16_t median(int16_t *p, uint16_t arr_size);

/**
 * @brief Calculate the difference between the maximum and minimum values in an array
 * @param p Pointer to the array
 * @param arr_size arr_size of the array
 * @return The difference between the maximum and minimum values in the array
 */
int16_t minmax(int16_t *p, uint16_t arr_size);

/**
 * @brief Calculate the variance of an array
 * @param p Pointer to the array
 * @param arr_size arr_size of the array
 * @return The variance of the array
 */
int32_t variance(int16_t *p, uint16_t arr_size);

/**
 * @brief Calculate the covariance of two arrays
 * @param p1 Pointer to the first array
 * @param p2 Pointer to the second array
 * @param arr_size arr_size of the arrays
 * @return The covariance of the two arrays
 */
int32_t covariance(int16_t *p1, int16_t *p2, uint16_t arr_size);

/**
 * @brief Calculate the standard deviation of an array
 * @param p Pointer to the array
 * @param arr_size arr_size of the array
 * @return The standard deviation of the array
 */
int32_t stddev(int16_t *p, uint16_t arr_size);

/**
 * @brief Calculate the quotient of two integers and map the result from [0,1] to [0,256]
 * @param dividend The dividend
 * @param divisor The divisor
 * @return The percent mapped to the range [0,256]
 */
uint8_t Percent2Byte(int dividend, int divisor);

/**
 * @brief Calculate the quotient of the value times the factor
 * @param value The value
 * @param percentTimes256 The percent times 256
 * @return The quotient mapped to the range [0, 256]
 */
int16_t Percent2Result(int16_t value, uint8_t percentTimes256);

/**
 * @brief Calculate the quotient of the value times the factor
 * @param value The value
 * @param percentTimes256 The percent times 256
 * @return The quotient mapped to the range [0, 256]
 */
uint32_t uint32_log2(uint32_t inVal);
/***************************************
 * Array Sorting Functions
 ***************************************/
/**
 * @brief Sorts an array of integers in ascending order using bubble sort algorithm.
 * @param arr The array to be sorted.
 * @param arr_size The size of the array.
 */
void bubbleSortAscending(int16_t arr[], uint16_t arr_size);

/**
 * @brief Sorts an array of integers in descending order using bubble sort algorithm.
 * @param arr The array to be sorted.
 * @param arr_size The size of the array.
 */
void bubbleSortDescending(int16_t arr[], uint16_t arr_size);

/**
 * @brief Sorts an array of integers in ascending order using insertion sort algorithm.
 * @param arr The array to be sorted.
 * @param arr_size The size of the array.
 */
void insertSortAscending(int16_t arr[], uint16_t arr_size);

/**
 * @brief Sorts an array of integers in descending order using insertion sort algorithm.
 * @param arr The array to be sorted.
 * @param arr_size The size of the array.
 */
void insertSortDescending(int16_t arr[], uint16_t arr_size);

/***************************************
 * Array Search Functions
 ***************************************/

// Binary search function to locate a given value's position in a table.
unsigned int BinarySearch(unsigned int value, unsigned int *table, unsigned int arr_size, bool isDescending);

void test_num(void);

#endif    // __DEV_FILTER_H__
